package com.xjz.generate;

import cn.hutool.core.io.FileUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

/**
 * ClassName: CodeGenerator
 * Package: com.xjz.generate
 * Description:
 *  代码生成器
 * @Author 许小健
 * @Create 2025/8/2 16:15
 * @Version 1.0
 */

public class CodeGenerator {

    /**
     * 用法：修改生成参数和生成路径，注释掉不需要的生成逻辑，然后运行即可
     * @param args
     * @throws TemplateException
     * @throws IOException
     */
    public static void main(String[] args) throws TemplateException, IOException {
        String packageName = "com.xjz";
        String dataName = "用户评论";
        String dataKey = "userComment";
        String upperDataKey = "UserComment";

        //封装生成参数
        HashMap<String, Object> dataModel = new HashMap<>();
        dataModel.put("packageName",packageName);
        dataModel.put("dataName",dataName);
        dataModel.put("dataKey",dataKey);
        dataModel.put("upperDataKey",upperDataKey);

        //生成路径默认值
        String projectPath = System.getProperty("user.dir");
        //参考路径,可以调整下面的outputPath
        String inputPath = projectPath + File.separator + "src/main/resources/templdates/模板名称.java.ftl";
        String outputPath = String.format("%s/generator/包名/%s类后缀.java",projectPath,upperDataKey);

        //1.生成Controller
        //指定生成路径
        inputPath = projectPath + File.separator + "src/main/resources/templdates/TempldateController.java.ftl";
        outputPath = String.format("%s/generator/controller/%sController.java",projectPath,upperDataKey);

        //生成
        doGenerate(inputPath,outputPath,dataModel);
        System.out.println("生成 Controller 成功,文件路径:" + outputPath);


        // 2、生成 Service 接口和实现类
        // 生成 Service 接口
        inputPath = projectPath + File.separator + "src/main/resources/templates/TemplateService.java.ftl";
        outputPath = String.format("%s/generator/service/%sService.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        System.out.println("生成 Service 接口成功，文件路径：" + outputPath);
        // 生成 Service 实现类
        inputPath = projectPath + File.separator + "src/main/resources/templates/TemplateServiceImpl.java.ftl";
        outputPath = String.format("%s/generator/service/impl/%sServiceImpl.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        System.out.println("生成 Service 实现类成功，文件路径：" + outputPath);


        // 3、生成数据模型封装类（包括 DTO 和 VO）
        // 生成 DTO
        inputPath = projectPath + File.separator + "src/main/resources/templates/model/TemplateAddRequest.java.ftl";
        outputPath = String.format("%s/generator/model/dto/%sAddRequest.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        inputPath = projectPath + File.separator + "src/main/resources/templates/model/TemplateQueryRequest.java.ftl";
        outputPath = String.format("%s/generator/model/dto/%sQueryRequest.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        inputPath = projectPath + File.separator + "src/main/resources/templates/model/TemplateEditRequest.java.ftl";
        outputPath = String.format("%s/generator/model/dto/%sEditRequest.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        inputPath = projectPath + File.separator + "src/main/resources/templates/model/TemplateUpdateRequest.java.ftl";
        outputPath = String.format("%s/generator/model/dto/%sUpdateRequest.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        System.out.println("生成 DTO 成功，文件路径：" + outputPath);

        // 生成 VO
        inputPath = projectPath + File.separator + "src/main/resources/templates/model/TemplateVO.java.ftl";
        outputPath = String.format("%s/generator/model/vo/%sVO.java", projectPath, upperDataKey);
        doGenerate(inputPath, outputPath, dataModel);
        System.out.println("生成 VO 成功，文件路径：" + outputPath);
    }


    /**
     * 生成文件
     * @param inputPath 模板文件输入路径
     * @param outputPath 输出路径
     * @param model     数据模型
     * @throws IOException
     * @throws TemplateException
     */
    private static void doGenerate(String inputPath, String outputPath, Object model) throws IOException, TemplateException {
        // new 出 Configuration 对象,参数为 FreeMarker 版本号
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);

        //指定模板文件所在的路径
        File templateDir = new File(inputPath).getParentFile();
        configuration.setDirectoryForTemplateLoading(templateDir);

        //设置模板文件使用的字符集
        configuration.setDefaultEncoding("utf-8");

        //创建模板对象，加载指定模板
        String templdateName = new File(inputPath).getName();
        Template template = configuration.getTemplate(templdateName);

        //文件不存在则创建文件和父目录
        if (!FileUtil.exist(outputPath)) {
            FileUtil.touch(outputPath);
        }

        //生成
        FileWriter out = new FileWriter(outputPath);
        template.process(model,out);

        //生成文件后要关闭资源
        out.close();
    }
}
